﻿using System;
using System.Data;
using System.Configuration;
using System.Xml;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;

/// <summary>
/// FileName: XMLHelper
/// Author: ziyou
/// Create Date: 2008-9-28
/// Email: ysli_195@163.com
/// Version: 1.0.0.3
/// Rewrite: 2009-2-3
/// </summary>
namespace Commons
{

    public class XmlHelper
    {
        public XmlHelper()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public static byte[] EntityToBinary(object entity)
        {
            if (entity == null) return null;
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, entity);
            byte[] rets = ms.ToArray();
            ms.Close();
            return rets;
        }

        public static object BinaryToEntity(byte[] input)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream(input);
            object ret = bf.Deserialize(ms);
            ms.Close();
            return ret;
        }

        public static ArrayList GetValueTypeList()
        {
            ArrayList valueTypeList = new ArrayList();
            valueTypeList.Add(typeof(int));
            valueTypeList.Add(typeof(double));
            valueTypeList.Add(typeof(string));
            valueTypeList.Add(typeof(bool));
            valueTypeList.Add(typeof(long));
            valueTypeList.Add(typeof(decimal));
            return valueTypeList;
        }

        public static string EntityToXML(object entity,string intends)
        {
            if (entity == null) return "";

            StringBuilder str = new StringBuilder();

            string intend = "    " + intends;
            

            if ((entity.GetType().IsArray || entity is IEnumerable) && !entity.GetType().Equals(typeof(string)))
            {
                str.Append(intends + "<" + entity.GetType().DeclaringType.Name + ">\r\n");

                foreach (object obj in (IEnumerable)entity)
                {
                    //str.AppendLine(intend + "<" + entity.GetType().Name + ">");
                    str.Append(XmlHelper.EntityToXML(obj, intend));
                    //str.AppendLine(intend + "</" + entity.GetType().Name + ">");
                }
            }
            else
            {
                str.Append(intends + "<" + entity.GetType().DeclaringType.Name + ">\r\n");
                PropertyInfo[] props = entity.GetType().GetProperties(BindingFlags.Public |
                                            BindingFlags.Static |
                                            BindingFlags.NonPublic |
                                            BindingFlags.Instance);
                foreach (PropertyInfo info in props)
                {
                    object valueObj = info.GetValue(entity, null);
                    if ((valueObj is IEnumerable || info.PropertyType.IsArray) && !XmlHelper.GetValueTypeList().Contains(info.PropertyType))
                    {
                        str.AppendLine(intend + "<" + info.Name + ">");
                        foreach (object obj in (IEnumerable)valueObj)
                        {
                            str.Append(XmlHelper.EntityToXML(obj, intend));
                        }
                        str.AppendLine(intend + "</" + info.Name + ">\r\n");
                    }
                    else
                    {
                        string value = valueObj == null ? "" : valueObj.ToString();
                        
                        str.Append(intend + "<" + info.Name + " type=\"" + info.PropertyType.Name  + "\">");
                        if (typeof(string).Equals(info.PropertyType) && !string.IsNullOrEmpty(value))
                        {
                            str.Append("<![CDATA[" + value + "]]>");
                        }
                        else
                        {
                            str.Append(value);
                        }
                        str.Append("</" + info.Name + ">\r\n");
                    }
                }
            }
            str.AppendLine(intends + "</" + entity.GetType().Name + ">");
            return str.ToString();
        }

        public static object XmlToEntity(string xml)
        {
            object vo = null;
            XmlDocument xdoc = new XmlDocument();
            try
            {
                CodeGen cg = new CodeGen();
                xdoc.LoadXml(xml);
                XmlElement root = xdoc.DocumentElement;
                if (root != null)
                {
                    vo = cg.GetObject(root.Name);
                    if (vo == null) return null;
                }

            }
            catch (Exception ex)
            {
                return null;
            }

            return vo;
        }

        public static string DataTableToXml()
        {
            return "";
        }
  
    }


}